/*
Copyright  2018 Blockchain Technology and Application Joint Lab, Fintech Research Center of ISCAS.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */
import settings from '../../setting.js';
import Protobuf from 'protobufjs';
import uuidv1 from 'uuid/v1';
import crypto from 'crypto';
import {Sign, verifySign} from '../api/cryptoHelper'
import root from '../repchainMessage';
import Long from 'Long';

settings = new settings();
/**
 * 创建交易
 * @param chainCode 链码
 * @param prv_key_pem 私钥
 * @param account_address 账户短地址
 * @param cb 回调函数
 */
exports.createTransaction = function (chainCodeFun,chinaCodeArgs, prv_key_pem, account_address, cb) {
    let t_chaincodeID = root.rep.protos.ChaincodeID.create({
        path: settings.chainCodeId_path,
        name: settings.chainCodeId_name
    });

    let t_chaincodeInput = root.rep.protos.ChaincodeInput.create({function: chainCodeFun, args:chinaCodeArgs});

    let t_chaincodeSpec = root.rep.protos.ChaincodeSpec.create({
        chaincodeID: t_chaincodeID,
        ctorMsg: t_chaincodeInput,
        timeout: 1000,
        secureContext: 'secureContext',
        codePackage: new Buffer('string', 'utf8'),
        ctype:root.rep.protos.ChaincodeSpec.CodeType.CODE_JAVASCRIPT
    });

    let t_chaincodeID_str = "path: \"" + settings.chainCodeId_path + "\"\n" + "name: \"" + settings.chainCodeId_name + "\"\n";
    let millis = Date.now();
    let timestamp_json = {seconds: new Long(millis / 1000), nanos: ((millis % 1000) * 1000000)};//{seconds: parseInt(millis / 1000), nanos: ((millis % 1000) * 1000000)};

    let t_json = {
        type: root.rep.protos.Transaction.Type.CHAINCODE_INVOKE,
        chaincodeID: new Buffer(t_chaincodeID_str, 'utf8'),
        payload: t_chaincodeSpec,
        metadata: null,
        txid: uuidv1(),
        timestamp: root.google.protobuf.Timestamp.create(timestamp_json),
        confidentialityLevel: root.rep.protos.ConfidentialityLevel.PUBLIC,
        confidentialityProtocolVersion: 'confidentialityProtocolVersion-1.0',
        nonce: new Buffer('nonce', 'utf8'),
        toValidators: new Buffer('toValidators', 'utf8'),
        cert: new Buffer(account_address, 'utf8'),
    }
    let err = root.rep.protos.Transaction.verify(t_json)
    if (err)
        throw Error(err);
    let transaction = root.rep.protos.Transaction.create(t_json);
    let t_bytes = new Buffer(root.rep.protos.Transaction.encode(transaction).finish());
    // To sign the sha256 result bytearray above and results a signature which is a bytearray
    // Using SHA1 algorithm which is same with repchain's verify algorithm
    // PEM format PrvKey and PubKey are exported from mykeystore_1.jks utilizing keystore tool 
    let signature = Sign('ecdsa-with-SHA1', prv_key_pem, t_bytes);
    transaction.signature = signature;
    t_bytes = new Buffer(root.rep.protos.Transaction.encode(transaction).finish());
    let t_bytes_hex_str = t_bytes.toString('hex');
    cb(t_bytes_hex_str, transaction.txid);


}